<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:pbs="http://schema.pbs.gov.au"
    xmlns:int="http://schema.pbs.gov.au/DoHA-Internal"
    xmlns:rwt="http://schema.pbs.gov.au/RWT/"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dbk="http://docbook.org/ns/docbook"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    
    <dbk:article>
        <dbk:info>
            <dbk:title>Support Module</dbk:title>
            
            <dbk:copyright>
                <dbk:year>2013</dbk:year>
                <dbk:year>2012</dbk:year>
                <dbk:year>2011</dbk:year>
                <dbk:year>2009</dbk:year>
                <dbk:holder>Commonwealth of Australia</dbk:holder>
            </dbk:copyright>
            
            <dbk:legalnotice>
                <dbk:para>This software is copyrighted by the Commonwealth of Australia ("The Commonwealth").
                    The following terms apply to all files associated with the software unless explicitly
                    disclaimed in individual files.</dbk:para>
                <dbk:para>Permission is hereby granted to use, copy, modify, distribute, and license this
                    software and its documentation for any purpose, provided that existing copyright notices
                    are retained in all copies and that this notice is included verbatim in any distributions.
                    No written agreement, license, or royalty fee is required for any of the authorized uses.
                    Modifications to this software may be copyrighted by their authors and need not follow the
                    licensing terms described here, provided that the new terms are clearly indicated on the
                    first page of each file where they apply.</dbk:para>
                <dbk:para>IN NO EVENT SHALL THE COMMONWEALTH OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
                    DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
                    THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE
                    BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</dbk:para>
                <dbk:para>THE COMMONWEALTH SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
                    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
                    NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE COMMONWEALTH HAS
                    NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
                    MODIFICATIONS.</dbk:para>
            </dbk:legalnotice>
            
            <dbk:author>
                <dbk:personname>Steve Ball</dbk:personname>
                <dbk:email>Steve.Ball@health.gov.au</dbk:email>
                <dbk:affiliation>
                    <dbk:orgname>Department of Health and Ageing</dbk:orgname>
                    <dbk:orgdiv>PharmBiz</dbk:orgdiv>
                </dbk:affiliation>
            </dbk:author>
            
            <dbk:revhistory>
                <dbk:revision>
                    <dbk:revnumber>1.3.1</dbk:revnumber>
                    <dbk:date>2013-11-06</dbk:date>
                    <dbk:authorinitials>SRB</dbk:authorinitials>
                    <dbk:revremark>Fix restriction level.</dbk:revremark>
                </dbk:revision>
                <dbk:revision>
                    <dbk:revnumber>1.3</dbk:revnumber>
                    <dbk:date>2013-11-06</dbk:date>
                    <dbk:authorinitials>SRB</dbk:authorinitials>
                    <dbk:revremark>Add restriction level of prescribing rules to before and after elements.</dbk:revremark>
                </dbk:revision>
                <dbk:revision>
                    <dbk:revnumber>1.2</dbk:revnumber>
                    <dbk:date>2013-07-17</dbk:date>
                    <dbk:authorinitials>SRB</dbk:authorinitials>
                    <dbk:revremark>Fix processing of altered prescribing rules.</dbk:revremark>
                </dbk:revision>
                <dbk:revision>
                    <dbk:revnumber>1.1</dbk:revnumber>
                    <dbk:date>2012-11-07</dbk:date>
                    <dbk:authorinitials>SRB</dbk:authorinitials>
                    <dbk:revremark>Change DocBook namespace prefix.</dbk:revremark>
                </dbk:revision>
                <dbk:revision>
                    <dbk:revnumber>1.0</dbk:revnumber>
                    <dbk:date>2012-10-01</dbk:date>
                    <dbk:authorinitials>SRB</dbk:authorinitials>
                    <dbk:revremark>Initial version.</dbk:revremark>
                </dbk:revision>
            </dbk:revhistory>
        </dbk:info>
        
        <dbk:para>This XSL stylesheet pre-processes a PBS XML document to resolve change data.</dbk:para>
        <dbk:para>The source document is a PBS XML document.</dbk:para>
        <dbk:para>The result document is a modified XML document.</dbk:para>
    </dbk:article>
    
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:preserve-space elements="dbk:para"/>

    <xsl:key name="adds" match="pbs:addition" use="pbs:any-reference/@xlink:href"/>
    <xsl:key name="changes" match="pbs:alteration" use="pbs:any-reference/@xlink:href"/>
    <xsl:key name="deletes" match="pbs:deletion" use="@xlink:href"/>

    <xsl:template match="pbs:listings-list">
        <xsl:choose>
            <xsl:when
                test="pbs:info/pbs:pricing-model = 'http://schema.pbs.gov.au/Pricing/extemporaneous'"/>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                    <xsl:apply-templates
                        select="key('deletes', concat('#', @xml:id))/pbs:previous/*" mode="deleted"
                    />
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="pbs:prescribing-rule">
        <xsl:choose>
            <xsl:when test="not(pbs:ready-prepared | pbs:infusible)"/>
            <xsl:otherwise>
                <xsl:variable name="change-node" select="key('changes', concat('#', @xml:id))"/>

                <xsl:copy>
                    <xsl:apply-templates select="@*"/>
                    <before>
                        <xsl:choose>
                            <xsl:when test="$change-node and
                                count($change-node/pbs:previous/*/node()) = 0">
                                <xsl:attribute name="type">
                                    <xsl:value-of select="$change-node/pbs:previous/*/@type"/>
                                </xsl:attribute>
                                <xsl:apply-templates select="node()" mode="before"/>
                            </xsl:when>
                            <xsl:when test="$change-node/pbs:previous/*/node()">
                                <xsl:attribute name="type">
                                    <xsl:value-of select="$change-node/pbs:previous/*/@type"/>
                                </xsl:attribute>
                                <xsl:apply-templates
                                    select="$change-node/pbs:previous/*/node()"
                                    mode="before"/>
                            </xsl:when>
                            <xsl:when test="not(key('adds', concat('#', @xml:id)))">
                                <xsl:attribute name="type">
                                    <xsl:value-of select="@type"/>
                                </xsl:attribute>
                                <xsl:apply-templates select="node()" mode="before"/>
                            </xsl:when>
                        </xsl:choose>
                    </before>
                    <after type="{@type}">
                        <xsl:apply-templates select="node()"/>
                    </after>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="pbs:prescribing-rule" mode="deleted">
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="before"/>
            <before type="{@type}">
                <xsl:apply-templates select="node()" mode="before"/>
            </before>
            <after/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*" mode="deleted">
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="before"/>
            <xsl:apply-templates select="node()" mode="before"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="rwt:restrictions-list">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:apply-templates select="key('deletes', concat('#', @xml:id))/pbs:previous/*"
                mode="deleted"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="rwt:restrictions-list/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:choose>
            <xsl:when test="key('changes', concat('#', @xml:id))">
                <xsl:apply-templates select="key('changes', concat('#', @xml:id))/pbs:previous/*"
                    mode="before">
                    <xsl:with-param name="after" select="."/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()" mode="before"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="@*|*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*" mode="before">
        <xsl:param name="after" select="/.."/>
        
        <xsl:variable name="node" select="key('changes', concat('#', @xml:id))"/>
        <xsl:choose>
            <xsl:when test="key('adds', concat('#', @xml:id))">
                <xsl:comment> element @xml:id="<xsl:value-of select="@xml:id"/>" has been added</xsl:comment>
            </xsl:when>
            <xsl:when test="$node">
                <xsl:element name="{name()}">
                    <xsl:apply-templates
                        select="$node/pbs:previous/*/@*"
                        mode="before"/>
                    <xsl:apply-templates
                        select="$node/pbs:previous/*/node()"
                        mode="before"/>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*" mode="before"/>
                    <xsl:if test="$after and
                        not(@xml:id) and
                        $after/@xml:id">
                        <xsl:attribute name="xml:id">
                            <xsl:value-of select="$after/@xml:id"/>
                            <xsl:text>-before</xsl:text>
                        </xsl:attribute>
                    </xsl:if>
                    <xsl:apply-templates select="node()" mode="before"/>
                    <xsl:apply-templates
                        select="key('deletes', concat('#', @xml:id))/pbs:previous/*" mode="before"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="@*" mode="before">
        <xsl:choose>
            <xsl:when test="name() = 'xml:id'">
                <xsl:attribute name="xml:id">
                    <xsl:value-of select="."/>
                    <xsl:text>-before</xsl:text>
                </xsl:attribute>
            </xsl:when>
            <xsl:when test="name() = 'xlink:href'">
                <xsl:attribute name="xlink:href">
                    <xsl:value-of select="."/>
                    <xsl:text>-before</xsl:text>
                </xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template
        match="pbs:changes-list |
        pbs:drugs-list |
        pbs:organisations-list |
        pbs:groups-list |
        rdf:RDF |
        pbs:pricing |
        rwt:alternate-text"/>
    <xsl:template match="pbs:pricing |
        rwt:alternate-text" mode="before"/>
</xsl:stylesheet>
